package de.hochschuletrier.bachelor.antfarm.entity;

import java.util.ArrayList;
import java.util.ConcurrentModificationException;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;

import de.hochschuletrier.bachelor.antfarm.constants.Constants;
import de.hochschuletrier.bachelor.antfarm.entity.listener.IEntityListener;
import de.hochschuletrier.bachelor.antfarm.entity.listener.IEntityMessageListener;
import de.hochschuletrier.bachelor.antfarm.entity.mes.ActionMessageGroup;
import de.hochschuletrier.bachelor.antfarm.world.World;

public abstract class Entity {
	protected int x;
	protected int y;
	protected Image image;
	protected String name;
	protected int id;
	
	private ArrayList<ActionMessageGroup> messages;
	private ArrayList<IEntityListener> entityListener;
	private ArrayList<IEntityMessageListener> messageListener;

	protected static int currentId = 0;

	public Entity(String name, int x, int y, Image image) {
		this.x = x;
		this.y = y;
		this.image = image;
		this.name = new String(name);
		this.messages = new ArrayList<ActionMessageGroup>();
		this.entityListener = new ArrayList<IEntityListener>();
		this.messageListener = new ArrayList<IEntityMessageListener>();

		this.id = currentId++;

		World.getInstance().addEntity(this);
	}

	public abstract void update(GameContainer gc, int delta);

	public void render(Graphics g, GameContainer gc) {
		if (image != null) {
			g.drawImage(image, x * Constants.TILESIZE, y * Constants.TILESIZE);
		}
		else {
			System.err.println(getName() + " (" + getId() + ") kennt sein Image nicht!");
		}
	}
	
	protected void setImage(Image image) {
		this.image = image;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
		alertListener();
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
		alertListener();
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = new String(name);
		alertListener();
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
		alertListener();
	}
	
	public void addMessage(ActionMessageGroup g) {
		messages.add(g);
		alertMessageListener(g);
	}
	
	public ArrayList<ActionMessageGroup> getMessages() {
		return messages;
	}
	
	protected void alertListener() {
		try {
			for (IEntityListener l : entityListener) {
				l.entityChanged(this);
			}
		}
		catch (ConcurrentModificationException e) {
			System.err.println(e);
			System.err.println("Listener ("+entityListener.size()+"):");
			for (IEntityListener l : entityListener) {
				System.err.println(l);
			}
			System.err.println();
			e.printStackTrace();
		}
	}
	
	private void alertMessageListener(ActionMessageGroup g) {
		for (IEntityMessageListener l : messageListener) {
			l.entityMessageAdded(g);
		}
	}
	
	public void addEntityListener(IEntityListener l) {
		entityListener.add(l);
	}
	
	public void removeEntityListener(IEntityListener l) {
		entityListener.remove(l);
	}
	
	public void addMessageListener(IEntityMessageListener l) {
		messageListener.add(l);
	}
	
	public void removeMessageListener(IEntityMessageListener l) {
		messageListener.remove(l);
	}
	
	@Override
	public String toString() {
		return getName() + " " + getId();
	}
}
